#coding=utf-8
from config import *

# 原型
class Prototype(object):

    # 初始化
    def __init__(self,image=None,face_orientation=RIGHT,name='',x=0,y=0,width=0,height=0,HP=3,ATK=1,DEF=0,status={}):
        self.image = image                                      # 应该显示的形象
        self.face_orientation = face_orientation                # 面向方向
        self.name = name                                        # 名称
        self.x, self.y = x, y                                    # 坐标
        self.width, self.height = width, height                 # 体型长宽
        self.HP = HP                                            # 防御力
        self.ATK = ATK                                          # 攻击力
        self.DEF = DEF                                          # 防御力
        self.status = status                                    # 状态字典
        self.move_time = 0                                      # 初始化移动时间
        self.move_rate = 200                                    # 移动速率 px/s
        self.attack_effects_status = False                      # 攻击特效显示状态

    # 根据人物当前位置绘制人物形象精灵
    def draw_sprite(self,target_Surface, skewing_vector=(0, 0)):
        target_Surface.blit(self.image, (self.x + skewing_vector[0], self.y + skewing_vector[1]))

    # 获取当前形象精灵的中心坐标
    def get_center_coordinate(self):
        return (self.x + self.image.get_width()//2,self.y + self.image.get_height()//2)

    # 判断与Prototype列表中的元素是否相交，有返回索引，没有返回-1
    def surface_intersect(self,Prototype_list):
        temp = 0
        for Prototype in Prototype_list:
            self_cx, self_cy = self.get_center_coordinate()
            pr_cx, pr_cy = Prototype.get_center_coordinate()
            self_rect = self.image.get_rect()
            pr_rect = Prototype.image.get_rect()
            if (self_rect.height / 3 + pr_rect.height / 3) < abs(self_cy - pr_cy) or (self_rect.width / 3 + pr_rect.width / 3) < abs(self_cx - pr_cx):
                break
            temp += 1
        if temp == len(Prototype_list) -1 or len(Prototype_list) == 0:
            temp = -1
        return temp

    # 控制移动
    def move(self,orientation,distance,Screen_size):
        '''orientation 移动方向 distance 移动距离(px)'''

        # 老虎的攻击也要移动，所以在这里转化一下
        if orientation in [RIGHT_GJ,RIGHT_JN]:
            orientation = RIGHT
        elif orientation in [LEFT_GJ,LEFT_JN]:
            orientation = LEFT


        if orientation == UP:
            self.y -= distance
        elif orientation == DOWN:
            self.y += distance
        elif orientation == LEFT:
            self.x -= distance
        elif orientation == RIGHT:
            self.x += distance
        elif orientation == LEFT_UP:
            self.x -= distance / 2
            self.y -= distance / 2
        elif orientation == LEFT_DOWN:
            self.x -= distance / 2
            self.y += distance / 2
        elif orientation == RIGHT_UP:
            self.x += distance / 2
            self.y -= distance / 2
        else:
            assert orientation == RIGHT_DOWN,'就八个方向，不会再多了吧'
            self.x += distance / 2
            self.y += distance / 2
        # 判定是否超出边界
        if self.y < 0:
            self.y = 0  # 不超过上边界
        if self.y > (Screen_size[1] - self.height):
            self.y = Screen_size[1] - self.height #不超过下边界
        if self.x < 0:
            self.x = 0  # 不超过左边界
        if self.x > (Screen_size[0] - self.width):
            self.x = Screen_size[0] - self.width  # 不超过右边界
    # 调整移动后的面向方向
    def adjust_face_orientation(self):
        # 移动后面向方向不能为45度方向
        if self.face_orientation in [LEFT_DOWN, LEFT_UP]:
            self.face_orientation = LEFT
        elif self.face_orientation in [RIGHT_DOWN, RIGHT_UP]:
            self.face_orientation = RIGHT
    # 普通攻击
    def normal_attack(self,Being):
        # 返回对方减少的血量
        # assert type(Being) == type(self),'攻击对象必须是生命体或其子类'
        difference = self.ATK - Being.DEF
        if difference > 0 :
            Being.HP -= difference
        return difference


# 攻击特效 - 明特萝莉(绿光球)
class GJEffects(object):
    def __init__(self,owner,coordinate=(0,0)):
        self.x = coordinate[0]
        self.y = coordinate[1]
        self.owner = owner          #拥有者
        self.image = None           #显示的精灵surface
        self.move_status = False    #移动状态
        self.move_orientation = ''  #移动方向
        self.GJ_effects_rate = 500  # 攻击特效移动速率 px/s

    # 根据坐标绘制出攻击特效,可以偏移（用于释放攻击后的移动显示）
    def draw_sprite_move(self,target_Surface, skewing_vector=(0, 0)):
        print('绘制前',self.image)
        target_Surface.blit(self.image,(self.x + skewing_vector[0],self.y + skewing_vector[1]))

    # 获取当前形象精灵的中心坐标
    def get_center_coordinate(self):
        return (self.x + self.image.get_width()//2,self.y + self.image.get_height()//2)

    # 判断与Prototype列表中的元素是否相交，有返回索引，没有返回-1
    def surface_intersect(self,Prototype_list):
        for Prototype in Prototype_list:
            self_cx, self_cy = self.get_center_coordinate()
            pr_cx, pr_cy = Prototype.get_center_coordinate()
            self_rect = self.image.get_rect()
            pr_rect = Prototype.image.get_rect()
            if (self_rect.height / 3 + pr_rect.height / 3) < abs(self_cy - pr_cy) and (self_rect.width / 3 + pr_rect.width / 3) < abs(self_cx - pr_cx):
                return Prototype_list.index(Prototype)
        return -1
    # 根据拥有者的坐标绘制出攻击特效（用于攻击时显示）
    def draw_sprite(self,target_Surface,GJ_skewing_distance=0):
        '''
        face_orientation --- 面向方向
        GJ_skewing_distance --- 距离拥有者中心点坐标的距离，当然得除去拥有者体型长宽
        '''
        assert issubclass(type(self.owner),Prototype), '拥有者必须是Prototype或其子类'
        center_coordinate = self.owner.get_center_coordinate()  # 获取拥有者的中心点坐标
        GJ_effects_center_coordinate = list(center_coordinate)
        # 计算攻击特效基于角色的偏移位置的中心点坐标
        if self.owner.face_orientation == UP:
            GJ_effects_center_coordinate[1] -= (GJ_skewing_distance + self.owner.height)
        elif self.owner.face_orientation == DOWN:
            GJ_effects_center_coordinate[1] += (GJ_skewing_distance + self.owner.height)
        elif self.owner.face_orientation == LEFT:
            GJ_effects_center_coordinate[0] -= (GJ_skewing_distance + self.owner.width)
        else:
            assert self.owner.face_orientation == RIGHT, '面向方向应该为右'
            GJ_effects_center_coordinate[0] += (GJ_skewing_distance + self.owner.width)
        # 根据中心坐标求出左上角坐标，这样才对称
        self.x = GJ_effects_center_coordinate[0] - self.image.get_width() / 2
        self.y = GJ_effects_center_coordinate[1] - self.image.get_height() / 2
        target_Surface.blit(self.image,(self.x, self.y))

# 明特萝莉
class MT(Prototype):
    def __init__(self,x=0,y=0):
        super(MT,self).__init__()
        self.x = x
        self.y = y
        self.name = 'MT'
        self.control = {}.fromkeys(MT_action_cmd_list,0)      # 根据行动指令生成动作控制器 上下左右攻击等,后面的值即代表开关，也代表顺序
        self.action_img_resource_dict = MT_action_img_resource_dict #资源字典
        self.resource_main_dir_path = MT_resource_main_dir_path  #资源主目录相对路径
        self.action_cmd_list = MT_action_cmd_list                #命令列表


    # 创建普通攻击特效
    def create_gj_effects(self,GJ_effects_coordinate=(0,0)):
        return GJEffects(self,GJ_effects_coordinate)

    # 获取对应动作的精灵的surface对象
    def get_action_surface(self,action,number=0):
        '''action 动作 number 动作步骤编号'''
        # print(action,number)
        assert self.action_img_resource_dict != None,'必须先加载精灵，才能获取相应的surface对象'
        return self.action_img_resource_dict[action][number]


# 敌方势力
class HostileForces(Prototype):
    move_orientation = ''
    # AI
    def update_image(HostileForces, player_image):
        pass


# 老虎
class Tiger(HostileForces):
    def __init__(self,x,y):
        super(Tiger,self).__init__()
        self.x = x
        self.y = y
        self.action_status = RIGHT  #行动状态
        self.move_rate = 150     # 移动速率，初始应该比玩家慢
        self.move_mode = 1       # 行走模式
        self.name = 'tiger'
        self.action_img_resource_dict = Tiger_action_img_resource_dict # 资源字典
        self.resource_main_dir_path = Tiger_resource_main_dir_path  # 资源主目录相对路径
        self.action_cmd_list = Tiger_action_cmd_list                # 命令列表
        self.GJ_status = False                                      # 攻击状态
        self.sprite_change_rate = 100                               # 精灵更换速率
        self.image = self.get_action_surface(LEFT)
        self.jn_surplus_cd_time = 0                                 # 技能剩余冷却时间
        self.jn_cd_time = 5*1000                                       # 技能冷却时间

    # 获取对应动作的精灵的surface对象
    def get_action_surface(self,action,number=0):
        '''action 动作 number 动作步骤编号'''
        # print(action,number)
        assert self.action_img_resource_dict != None,'必须先加载精灵，才能获取相应的surface对象'
        return self.action_img_resource_dict[action][number]